package edu.hubu.controller.impl;

import com.fasterxml.jackson.databind.ObjectMapper;
import edu.hubu.commons.Object2Map;
import edu.hubu.model.Password;
import edu.hubu.model.User;
import edu.hubu.service.impl.UserService;
import io.swagger.annotations.ApiOperation;
import net.moon.commons.EntityInfo;
import net.moon.commons.PageData;
import net.moon.commons.ResultsJson;
import net.moon.commons.StatusCode;
import net.moon.controller.CurdController;
import net.moon.jpa.service.DefaultService;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.web.bind.annotation.*;

import javax.imageio.ImageIO;
import javax.servlet.ServletContext;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.awt.*;
import java.awt.image.BufferedImage;
import java.util.Random;

/**
 * @author moonlan
 * @date 2020/10/27 下午1:55
 */
@RestController
@RequestMapping("/user")
public class UserController extends CurdController<User, String> {
    private final UserService service;
    private final ObjectMapper mapper;

    public UserController(DefaultService<User, String> service, ObjectMapper mapper) {
        this.service = (UserService) service;
        this.mapper = mapper;
    }

    @NotNull
    @Override
    protected User register() {
        return User.builder().build();
    }

    @PostMapping("/login")
    @ApiOperation("登录")
    public ResultsJson login(@RequestParam String userId, @RequestParam String userPassword, @RequestParam String checkCode, HttpServletRequest request) {
        return service.login(userId, userPassword, checkCode, request);
    }

    @PostMapping("/logout")
    @ApiOperation("登出")
    public ResultsJson logout(HttpServletRequest request, HttpServletResponse response, @RequestHeader String token) {
        return service.logout(request, response, token);
    }

    @PreAuthorize("hasAnyAuthority('findUser', 'find')")
    @NotNull
    @Override
    public ResultsJson findOneById(@NotNull @PathVariable("id") String id, @NotNull @RequestHeader String token) {
        User entityById = service.findEntityById(id);
        return ResultsJson.toJson(StatusCode.SUCCESS, 1, 0, entityById);
    }

    @PreAuthorize("hasAnyAuthority('findUser', 'find')")
    @NotNull
    @Override
    public ResultsJson findByLikePage(@RequestParam(value = "currentPage", defaultValue = "0") int currentPage, @RequestParam(value = "size", defaultValue = "8") int size, @Nullable @RequestBody EntityInfo entityInfo, @NotNull @RequestHeader String token) {
        PageData<User> paged = service.findEntitiesPaged(currentPage, size, entityInfo);
        return ResultsJson.toJson(StatusCode.SUCCESS, paged.getTotalSize(), paged.getCurrentPage(), paged.getData());
    }

    @PreAuthorize("hasAnyAuthority('findUser', 'find')")
    @NotNull
    @Override
    public ResultsJson findAllPage(@RequestParam(value = "currentPage", defaultValue = "0") int currentPage, @RequestParam(value = "size", defaultValue = "8") int size, @NotNull @RequestHeader String token) {
        PageData<User> paged = service.findEntitiesPaged(currentPage, size);
        return ResultsJson.toJson(StatusCode.SUCCESS, paged.getTotalSize(), paged.getCurrentPage(), paged.getData());
    }

    @PreAuthorize("hasAnyAuthority('updateUser', 'update')")
    @NotNull
    @Override
    public ResultsJson updateById(@NotNull @PathVariable("id") String id, @NotNull @RequestBody User t, @NotNull @RequestHeader String token) {
        User entity = service.updateEntityById(id, t);
        return ResultsJson.toJson(StatusCode.SUCCESS, 1, 0, entity);
    }

    @PreAuthorize("hasAnyAuthority('deleteUser', 'delete')")
    @NotNull
    @Override
    public ResultsJson deleteById(@NotNull @PathVariable("id") String id, @NotNull @RequestHeader String token) {
        boolean entityById = service.logicDeleteEntityById(id);
        return ResultsJson.toJson(StatusCode.SUCCESS, 1, 0, entityById);
    }

    @PreAuthorize("hasAnyAuthority('forbidUser', 'forbid')")
    @NotNull
    @Override
    public ResultsJson forbiddenById(@NotNull @PathVariable("id") String id, @NotNull @RequestHeader String token) {
        boolean entityById = service.forbidEntityById(id);
        return ResultsJson.toJson(StatusCode.SUCCESS, 1, 0, entityById);
    }

    @PreAuthorize("hasAnyAuthority('addUser', 'add')")
    @NotNull
    @Override
    public ResultsJson add(@NotNull @RequestBody User t, @NotNull @RequestHeader String token) {
        String userPassword = t.getUserPassword();
        String encode = new BCryptPasswordEncoder().encode(userPassword);
        t.setUserPassword(encode);
        User entity = service.addEntity(t);
        return ResultsJson.toJson(StatusCode.SUCCESS, 1, 0, entity);
    }

    @PreAuthorize("hasAnyAuthority('countUser', 'count')")
    @NotNull
    @Override
    public ResultsJson count(@NotNull @RequestHeader String token) {
        int count = service.getCount();
        return ResultsJson.toJson(StatusCode.SUCCESS, 1, 0, count);
    }

    @GetMapping("/code_paint")
    public void codePaint(HttpServletRequest request, HttpServletResponse response) throws Exception {
        //服务器通知浏览器不要缓存
        response.setHeader("pragma", "no-cache");
        response.setHeader("cache-control", "no-cache");
        response.setHeader("expires", "0");

        //在内存中创建一个长80，宽30的图片，默认黑色背景
        //参数一：长
        //参数二：宽
        //参数三：颜色
        int width = 80;
        int height = 30;
        BufferedImage image = new BufferedImage(width, height, BufferedImage.TYPE_INT_RGB);

        //获取画笔
        Graphics g = image.getGraphics();
        //设置画笔颜色为灰色
        g.setColor(Color.GRAY);
        //填充图片
        g.fillRect(0, 0, width, height);

        //产生4个随机验证码，12Ey
        String base = "0123456789ABCDEFGabcdefg";
        int size = base.length();
        Random r = new Random();
        StringBuilder sb = new StringBuilder();
        for (int i = 1; i <= 4; i++) {
            //产生0到size-1的随机值
            int index = r.nextInt(size);
            //在base字符串中获取下标为index的字符
            char c = base.charAt(index);
            //将c放入到StringBuffer中去
            sb.append(c);
        }
        String checkCode = sb.toString();
        System.out.println(checkCode);
        ServletContext context = request.getServletContext();
        context.setAttribute("CHECKCODE_SERVER", checkCode);
        String checkcodeServer = (String) context.getAttribute("CHECKCODE_SERVER");
        System.out.println(checkcodeServer);
        //设置画笔颜色为黄色
        g.setColor(Color.YELLOW);
        //设置字体的小大
        g.setFont(new Font("黑体", Font.BOLD, 24));
        //向图片上写入验证码
        g.drawString(checkCode, 15, 25);

        //将内存中的图片输出到浏览器
        ImageIO.write(image, "PNG", response.getOutputStream());

    }

    @PostMapping("/access")
    @PreAuthorize("hasAnyAuthority('toAdmin')")
    public ResultsJson access(@RequestHeader String token) {
        return ResultsJson.toJson(StatusCode.SUCCESS, 1, 1, true);
    }

    @PutMapping("/edit_password/{id}")
    @PreAuthorize("hasAnyAuthority('updateUser', 'update')")
    public ResultsJson editPwdById(@PathVariable("id") String id, @RequestBody Password password, @RequestHeader String token) {
        return service.editPwdById(id, password.getOldPassword(), password.getNewPassword());
    }
}
